package top.oneit.jdownload.controller.dialog;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.core.util.URLUtil;
import com.alibaba.fastjson.JSON;
import com.jfoenix.controls.JFXButton;
import com.jfoenix.controls.JFXCheckBox;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.fxml.FXML;
import javafx.scene.Cursor;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.scene.control.Tooltip;
import javafx.stage.DirectoryChooser;
import org.hibernate.Session;
import top.oneit.jdownload.component.JToast;
import top.oneit.jdownload.config.ApplicationConfig;
import top.oneit.jdownload.constants.JConstants;
import top.oneit.jdownload.constants.RequestMethod;
import top.oneit.jdownload.controller.BaseInitializable;
import top.oneit.jdownload.data.entity.AppConfig;
import top.oneit.jdownload.data.entity.DownloadFile;
import top.oneit.jdownload.data.entity.DownloadingTablePo;
import top.oneit.jdownload.stages.HomeStage;
import top.oneit.jdownload.stages.dialog.AddDownload;
import top.oneit.jdownload.stages.dialog.SelectSavePosition;
import top.oneit.jdownload.utils.StorageUtils;

import javax.swing.filechooser.FileSystemView;
import java.io.File;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.ResourceBundle;

/**
 * @author lingkang
 * @date 2021/11/10
 * qq: https://ab11d14e3bfba7f74d54bcfa98a35f5c.dlied1.cdntips.net/dl.softmgr.qq.com/original/im/QQ9.5.2.27905.exe?mkey=618fc0d974053852&f=d510&cip=116.5.30.167&proto=https
 */
public class SelectSavePositionController extends BaseInitializable {

    @FXML
    private Label labOpen;
    @FXML
    private TextField fileName, saveFolder, threadNumber;
    @FXML
    private JFXButton cancel, confirm;
    @FXML
    private Label fileSize;
    public JFXCheckBox autoExplain;

    private AppConfig appConfig;
    private Map<String, List<String>> header;
    private DownloadFile downloadFile = new DownloadFile();
    private Integer size = 0;
    private SelectSavePosition selectSavePosition = getStage(SelectSavePosition.class);

    @Override
    public void initialize(URL location, ResourceBundle resources) {
        init();
        labOpen.setOnMouseClicked(event -> {
            DirectoryChooser directoryChooser = new DirectoryChooser();
            directoryChooser.setInitialDirectory(new File("D:\\"));
            directoryChooser.setTitle("选择保存的目录");
            File file = directoryChooser.showDialog(labOpen.getScene().getWindow());
            if (file != null) {
                String path = file.getPath();//选择的文件夹路径
                System.out.println(path);
                saveFolder.setText(path);
            }
        });
        labOpen.setOnMouseEntered(event -> {
            labOpen.setCursor(Cursor.HAND);
        });
        labOpen.setTooltip(new Tooltip("打开文件夹选择保存位置"));

        initButton();
    }

    private void init() {
        header = selectSavePosition.responseHeader;
        appConfig = ApplicationConfig.getAppConfig();
        threadNumber.setText(appConfig.getDefaultThreadNumber().toString());

        if (appConfig.getDefaultSavePath() != null) {
            saveFolder.setText(appConfig.getDefaultSavePath());
        } else {
            File desktopDir = FileSystemView.getFileSystemView().getHomeDirectory();
            String desktopPath = desktopDir.getAbsolutePath();
            saveFolder.setText(desktopPath);
        }

        String downloadUrl = header.get("url").get(0).split("\\?")[0];
        String fn = URLUtil.decode(downloadUrl.substring(downloadUrl.lastIndexOf("/") + 1));
        String originalName = fn;
        if (new File(saveFolder.getText() + File.separator + fn).exists()) {
            if (fn.indexOf(".") != -1) {
                String suffix = FileUtil.getSuffix(fn);
                fn = fn.substring(0, fn.lastIndexOf(".")) + new SimpleDateFormat("_yyyyMMddHHmmss").format(new Date());
                fn += ("." + suffix);
            } else {
                fn += new SimpleDateFormat("_yyyyMMddHHmmss").format(new Date());
            }
            fileName.setText(fn);
        } else {
            fileName.setText(fn);
        }

        List<String> sizes = header.get("content-length");
        if (CollUtil.isEmpty(sizes)) {
            fileSize.setText("0 KB");
        } else {
            size = Integer.valueOf(sizes.get(0));
            fileSize.setText(StorageUtils.byteToString(size));
        }

        downloadFile.setOriginalName(originalName);
        downloadFile.setSize(size);
        downloadFile.setAutoExplain(autoExplain.isSelected());
        downloadFile.setHeadInfo(JSON.toJSONString(header));
        downloadFile.setUrl(downloadUrl);
    }

    private void initButton() {
        confirm.setOnAction(new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent event) {
                boolean directory = FileUtil.isDirectory(saveFolder.getText());
                if (!directory) {
                    new JToast().show(saveFolder.getText() + "\n这不是一个正确的保存目录", confirm);
                    return;
                }

                String path = saveFolder.getText() + File.separator + fileName.getText();
                if (new File(path).exists()) {
                    new JToast().show("文件已经存在：\n" + fileName.getText(), confirm);
                    return;
                }

                if (StrUtil.isEmpty(threadNumber.getText())) {
                    new JToast().show("线程数不能为空！", threadNumber);
                    return;
                } else {
                    Integer t = Integer.valueOf(threadNumber.getText());
                    if (t < 0 || t > 128) {
                        new JToast().show("线程数范围：1~128", threadNumber);
                        return;
                    }
                }

                if (StrUtil.isBlank(fileName.getText())) {
                    new JToast().show("文件名不能为空", fileName);
                    return;
                }

                Session session = getSession();
                session.beginTransaction();
                downloadFile.setStatus(JConstants.FILE_STATUS_NOT_FINISH);
                downloadFile.setSaveName(fileName.getText());
                downloadFile.setSavePath(saveFolder.getText());
                downloadFile.setThreadNumber(autoThreadNumber());
                downloadFile.setDownloadParam(selectSavePosition.history.getDownloadParam());
                downloadFile.setRequestMethod(
                        selectSavePosition.history.getDownloadParam().getBody() != null ? RequestMethod.POST : RequestMethod.GET
                );
                session.save(downloadFile);
                DownloadingTablePo po = new DownloadingTablePo();
                po.setDownloadFile(downloadFile);
                po.setTitle(fileName.getText());
                po.setSpeed(new Label("0 kb/s"));
                po.setSurplus(size);
                po.setSize(size);
                po.setStatus(JConstants.FILE_STATUS_AWAIT_DOWNLOAD);
                session.save(po);
                session.getTransaction().commit();
                // 刷新表格
                getStage(HomeStage.class).refreshTable();

                //关闭窗口
                selectSavePosition.close();
                getStage(AddDownload.class).close();
            }
        });

        cancel.setOnAction(new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent event) {
                // 关闭
                selectSavePosition.close();
            }
        });
    }

    /**
     * 对线程数进行优化
     *
     * @return
     */
    private Integer autoThreadNumber() {
        Integer number = Integer.valueOf(threadNumber.getText());
        if (size < 1024 * 1024 && number > 2) { //1 MB
            return 2;
        }
        if (size < 1024 * 1024 * 8 && number > 8) {
            return 8;
        }
        if (size < 1024 * 1024 * 32 && number > 32) {
            return 32;
        }
        return Integer.valueOf(threadNumber.getText());
    }

    public static void main(String[] args) {
        File desktopDir = FileSystemView.getFileSystemView().getHomeDirectory();
        String desktopPath = desktopDir.getAbsolutePath();
        System.out.println(desktopPath);
    }
}
